package com.mutual.base.controller;

import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.springframework.web.servlet.ModelAndView;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.mutual.base.page.PageResult;
import com.mutual.base.utils.JacksonUtil;
import com.mutual.base.utils.RandomUtil;
import com.mutual.base.utils.ReflectionUtil;
import com.mutual.constant.AdminSystemConstant;

public class BaseController {

	protected Log logger = LogFactory.getLog(getClass());

	public static final String STATUS_PARAMETER_NAME = "status";// 操作状态参数名称
	public static final String MESSAGE_PARAMETER_NAME = "message";// 操作消息参数名称
	public static final String TOKEN_PARAMETER_NAME = "token";	//操作token参数名称
	
	// 操作状态（警告、错误、成功）
	public enum Status {
		warn, error, success
	}
	
	/**
	 * 返回json数据
	 * @param status
	 * @param msg
	 * @return
	 */
	protected ModelAndView ajaxJSON(Status status){
		ModelAndView view = new ModelAndView("jsonView");
		Map<String,Object> data = view.getModel();
		data.put(STATUS_PARAMETER_NAME, status);
		
		return view;
	}
	
	/**
	 * 返回json数据
	 * @param status
	 * @param msg
	 * @return
	 */
	protected void ajax(Object object,HttpServletResponse response){
		try {
			response.setContentType("text/json;charset=UTF-8");
			response.setDateHeader("Expires", 1L);
			response.addHeader("Pragma", "no-cache");
			response.setHeader("Cache-Control", "no-cache, no-store, max-age=0");
			JacksonUtil.getMapper().writeValue(response.getWriter(), object);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 返回json数据
	 * @param status
	 * @param msg
	 * @return
	 */
	protected ModelAndView ajaxJSON(Status status,String msg){
		ModelAndView view = new ModelAndView("jsonView");
		Map<String,Object> data = view.getModel();
		data.put(STATUS_PARAMETER_NAME, status);
		data.put(MESSAGE_PARAMETER_NAME, msg);
		
		return view;
	}
	
	/**
	 * 返回json数据
	 * @param status
	 * @param msg
	 * @param needToken
	 * @return
	 */
	protected ModelAndView ajaxJSON(Status status,String msg,boolean needToken,HttpServletRequest request){
		ModelAndView view = new ModelAndView("jsonView");
		Map<String,Object> data = view.getModel();
		data.put(STATUS_PARAMETER_NAME, status);
		data.put(MESSAGE_PARAMETER_NAME, msg);
		
		if(needToken){
			String tokenVal = RandomUtil.uuid();
			request.getSession().setAttribute(AdminSystemConstant.SYS_TOKEN,tokenVal);
			data.put(TOKEN_PARAMETER_NAME, tokenVal);
		}
		
		return view;
	}
	
	protected ModelAndView ajaxJSON(Status status,String msg,Map<String,String> resultData,boolean needToken,HttpServletRequest request){
		ModelAndView view = new ModelAndView("jsonView");
		Map<String,Object> data = view.getModel();
		data.put(STATUS_PARAMETER_NAME, status);
		data.put(MESSAGE_PARAMETER_NAME, msg);
		
		if(null != resultData){
			for(Map.Entry<String, String> entry : resultData.entrySet()){
				data.put(entry.getKey(), entry.getValue());
			}
			
			resultData.clear();
			resultData = null;
		}
		
		if(needToken){
			String tokenVal = RandomUtil.uuid();
			request.getSession().setAttribute(AdminSystemConstant.SYS_TOKEN,tokenVal);
			data.put(TOKEN_PARAMETER_NAME, tokenVal);
		}
		return view;
	}
	
	protected ModelAndView ajaxJSON(Status status,String msg,Map<String,String> resultData){
		ModelAndView view = new ModelAndView("jsonView");
		Map<String,Object> data = view.getModel();
		data.put(STATUS_PARAMETER_NAME, status);
		data.put(MESSAGE_PARAMETER_NAME, msg);
		
		if(null != resultData){
			for(Map.Entry<String, String> entry : resultData.entrySet()){
				data.put(entry.getKey(), entry.getValue());
			}
			
			resultData.clear();
			resultData = null;
		}
		return view;
	}
	
	protected ModelAndView ajaxJSON(Status status,String msg,JSONArray root){
		ModelAndView view = new ModelAndView("jsonView");
		Map<String,Object> data = view.getModel();
		data.put(STATUS_PARAMETER_NAME, status);
		data.put(MESSAGE_PARAMETER_NAME, msg);
		data.put("data", root);
		
		return view;
	}
	
	protected void ajaxJSON(JSONObject json, HttpServletResponse response){
		try {
			response.setContentType("text/json;charset=UTF-8");
			response.setDateHeader("Expires", 1L);
			response.addHeader("Pragma", "no-cache");
			response.setHeader("Cache-Control", "no-cache, no-store, max-age=0");
			JacksonUtil.getMapper().writeValue(response.getWriter(), json);
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		}
	}
	
	protected ModelAndView ajaxHTML(Status status,String msg,Map<String,String> resultData){
		ModelAndView view = new ModelAndView("htmlView");
		Map<String,Object> data = view.getModel();
		data.put(STATUS_PARAMETER_NAME, status);
		data.put(MESSAGE_PARAMETER_NAME, msg);
		
		if(null != resultData){
			for(Map.Entry<String, String> entry : resultData.entrySet()){
				data.put(entry.getKey(), entry.getValue());
			}
			
			resultData.clear();
			resultData = null;
		}
		return view;
	}
	
	/**
	 * 输入分页数据
	 * @param root
	 * @param response
	 */
	@SuppressWarnings("unchecked")
	protected void ajaxPageResult(JSONObject root,HttpServletResponse response) {
		try{
			response.setContentType("text/json;charset=UTF-8");
			response.setDateHeader("Expires", 1L);
			response.addHeader("Pragma", "no-cache");
			response.setHeader("Cache-Control", "no-cache, no-store, max-age=0");
			root.put(STATUS_PARAMETER_NAME, Status.success);
			JacksonUtil.getMapper().writeValue(response.getWriter(), root);
		}catch(Exception ex){
			logger.error(ex.getMessage(),ex);
		}
	}
	
	/**
	 * 输入分页数据
	 * @param root
	 * @param response
	 */
	@SuppressWarnings("unchecked")
	protected void ajaxPageResult(JSONObject root,HttpServletResponse response,String dateFormat) {
		try{
			response.setContentType("text/json;charset=UTF-8");
			response.setDateHeader("Expires", 1L);
			response.addHeader("Pragma", "no-cache");
			response.setHeader("Cache-Control", "no-cache, no-store, max-age=0");
			root.put(STATUS_PARAMETER_NAME, Status.success);
			ObjectMapper mapper = JacksonUtil.getMapper();
			mapper.setDateFormat(new SimpleDateFormat(dateFormat));
			mapper.writeValue(response.getWriter(), root);
		}catch(Exception ex){
			logger.error(ex.getMessage(),ex);
		}
	}
	
	/**
	 * 获取网站地址
	 * @param request
	 * @return
	 */
	protected String getBaseUrl(HttpServletRequest request){
		String path = request.getContextPath();
		StringBuffer basePath = new StringBuffer();
		basePath.append(request.getScheme());
		basePath.append("://");
		basePath.append(request.getServerName());
		int port = request.getServerPort();
		if(port != 80){
			basePath.append(":").append(port);
		}
		basePath.append(path).append("/");
		return basePath.toString();
	}
	
	/**
	 * 获取真实路径
	 * @param request
	 * @return
	 */
	protected String getRealPath(String path,HttpServletRequest request){
		String realPath = request.getSession().getServletContext().getRealPath(path);
		return realPath;
	}
		
	/**
	 * 获取IP地址
	 * @param request
	 * @return
	 */
	protected String getIpAddr(HttpServletRequest request){
		String ip = request.getHeader("X-Real-IP");
		if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("X-Forwarded-For");
		} else {
			return ip;
		}
		if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getRemoteAddr();
		} else {
			int index = ip.indexOf(',');
			if (index != -1) {
				ip = ip.substring(0, index);
			}
		}
		return ip;
	}
	
	/**
	 * 生成JSONObject对象
	 * @param itemList
	 */
	@SuppressWarnings("unchecked")
	public static JSONObject toJsonResultList(List<?> itemList,String[] includeProperties) {
		JSONObject root = new JSONObject();
		JSONArray array = new JSONArray();
		root.put("resultList", array);
		
		for(int i=0;i<itemList.size();i++){
			JSONObject json = new JSONObject();
			Object obj = itemList.get(i);
			for(String includeProperty : includeProperties){
				json.put(includeProperty,ReflectionUtil.invokeGetterMethod(obj, includeProperty));
			}
			array.add(json);
		}
		return root;
	}
	
	/**
	 * 分页json构建
	 * 
	 * @param page
	 *            分页信息
	 * @param resultList
	 *            结果集json数组
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static JSONObject toPageJson(@SuppressWarnings("rawtypes") PageResult pageResult,String[] includeProperties) {
		JSONObject jsonObject = new JSONObject();
		try {
			jsonObject.put("total", pageResult.getRows());
			jsonObject.put("pageResult.allPages", pageResult.getAllPages());
			
			JSONArray array = new JSONArray();
			jsonObject.put("resultList", array);
			
			for(int i=0;i<pageResult.getResult().size();i++){
				JSONObject json = new JSONObject();
				Object obj = pageResult.getResult().get(i);
				for(String includeProperty : includeProperties){
					json.put(includeProperty,ReflectionUtil.invokeGetterMethod(obj, includeProperty));
				}
				array.add(json);
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		return jsonObject;
	}
	
}
